import { PlayerGroup } from "@sapi-game/gamePlayer/playerGroup";
import { Game, GameComponent } from "@sapi-game/main";
import { ElevatorCatPlayer } from "@/elevatorCat/player";
import { eleCatchState } from "../state";

export class ElevatorLocatorComponent extends GameComponent<eleCatchState> {
    override onAttach(): void {
        this.subscribe(
            Game.events.itemUse,
            (t) => {
                const ans = this.context.group.findById(t.source.id);
                if (ans?.player) {
                    this.handlelocate(ans.group, ans.player);
                }
            },
            { itemId: "minecraft:compass" }
        );
    }

    handlelocate(group: PlayerGroup<ElevatorCatPlayer>, p: ElevatorCatPlayer) {
        if (p.locateCooldown > 0) {
            return p.sendMessage(`请等待§e${p.locateCooldown}§r秒再定位`);
        }
        if (group == this.context.cat) {
            const locatedPlayer = this.findNearest(this.context.mouse, p);
            if (locatedPlayer) {
                p.title(
                    locatedPlayer.name,
                    `在第${this.context.utils.calcFloor(
                        locatedPlayer.location.y
                    )}层`
                );
                p.locateCooldown = this.context.config.locateCooldownCat;
            } else {
                p.sendMessage("未定位到玩家");
                p.locateCooldown = 5;
            }
        }
    }

    findNearest(
        targetTeam: PlayerGroup<ElevatorCatPlayer>,
        p: ElevatorCatPlayer
    ) {
        if (!p.player) return;
        const players = targetTeam
            .filter((p) => p.lives > 0)
            .map((p) => p.player)
            .filter((p) => p != undefined);
        if (players.length == 0) return;
        const floor = this.context.utils.calcFloor(p.player.location.y);
        return players.reduce((nearest, current) => {
            const nearestFloor = this.context.utils.calcFloor(
                nearest.location.y
            );
            const currentFloor = this.context.utils.calcFloor(
                current.location.y
            );

            const nearestDiff = Math.abs(nearestFloor - floor);
            const currentDiff = Math.abs(currentFloor - floor);

            return currentDiff < nearestDiff ? current : nearest;
        });
    }
}
